package com.nuoniu.sibanyun.service.crm.call.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.nuoniu.sibanyun.common.exception.NuoNiuException;
import com.nuoniu.sibanyun.common.lang.StringUtils;
import com.nuoniu.sibanyun.entity.crm.call.CrmCallMode;
import com.nuoniu.sibanyun.entity.crm.call.CrmCallTask;
import com.nuoniu.sibanyun.entity.crm.call.CrmCallTaskRecord;
import com.nuoniu.sibanyun.entity.crm.call.dto.AddPhoneDto;
import com.nuoniu.sibanyun.entity.crm.call.dto.CrmCallTaskDto;
import com.nuoniu.sibanyun.entity.crm.call.dto.CrmCallTaskPhoneDto;
import com.nuoniu.sibanyun.entity.crm.call.dto.CrmCallTaskUpdateDto;
import com.nuoniu.sibanyun.mapper.crm.call.CrmCallTaskMapper;
import com.nuoniu.sibanyun.service.crm.ICrmCustomerService;
import com.nuoniu.sibanyun.service.crm.ICrmLinkmanService;
import com.nuoniu.sibanyun.service.crm.call.ICrmCallTaskDetailService;
import com.nuoniu.sibanyun.service.crm.call.ICrmCallTaskRecordService;
import com.nuoniu.sibanyun.service.crm.call.ICrmCallTaskService;
import com.nuoniu.sibanyun.userThread.UserInfo;
import com.nuoniu.sibanyun.userThread.UserThreadLocal;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Period;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 客户管理-外呼任务管理 服务实现类
 * </p>
 *
 * @author 白强
 * @since 2022-02-28
 */
@Service
@Log4j2
public class CrmCallTaskServiceImpl extends ServiceImpl<CrmCallTaskMapper, CrmCallTask> implements ICrmCallTaskService {

    /** 校验 数字 用逗号 隔开 的字符串 */
    private static final String STR_ENG_PATTERN="^\\d+(,\\d+)*$";

    @Autowired
    private ICrmCallTaskDetailService callTaskDetailService;
    @Autowired
    @Lazy
    private ICrmCustomerService customerService;
    @Autowired
    private ICrmLinkmanService linkmanService;

    @Override
    public Page<CrmCallTask> pageList(CrmCallTaskDto crmCallTaskDto) {
        UserInfo userInfo = UserThreadLocal.get();
        String createUserIds = crmCallTaskDto.getCreateUserIds();
        if(StringUtils.isNotBlank(createUserIds) && !createUserIds.matches(STR_ENG_PATTERN)) {
            throw new NuoNiuException("参数错误");
        }
        Page<CrmCallTask> page = baseMapper.page(crmCallTaskDto.getPage(), crmCallTaskDto, userInfo.getCompanyId(), userInfo.getUserId());
        return page;
    }

    @Override
    public CrmCallTask detailById(Long id) {
        CrmCallTask crmCallTask = getById(id);
        if(null == crmCallTask) {
            throw new NuoNiuException("外呼任务不存在");
        }
        return crmCallTask;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void saveTask(CrmCallTask crmCallTask) {
        UserInfo userInfo = UserThreadLocal.get();
        Long id = crmCallTask.getId();
        String remarks = crmCallTask.getRemarks();
        LocalDate startTime = crmCallTask.getStartTime();
        LocalDate endTime = crmCallTask.getEndTime();
        if(null == startTime || null == endTime ){
            throw new NuoNiuException("执行时间不能为空");
        }
        Period between = Period.between(startTime, endTime);
//        long diffMinutes = between.toMinutes();
//        if(diffMinutes < 10)throw new NuoNiuException("执行时间差必须大于10分钟");
        long diffDays = between.getDays();
        if(diffDays < 0) {
            throw new NuoNiuException("执行时间差不能小于0天");
        }
        if(diffDays > 6) {
            throw new NuoNiuException("执行时间差不能大于7天");
        }
        if(null == id){
            crmCallTask.setCompanyId(userInfo.getCompanyId());
            crmCallTask.setCreateUserId(userInfo.getUserId());
            crmCallTask.setCreateUserName(userInfo.getRealName());
            crmCallTask.setCreateDate(LocalDateTime.now());
            crmCallTask.setStatus(0);
        }else{
            CrmCallTask oldCrmCallTask = getById(id);
            Integer businessStatus = oldCrmCallTask.getBusinessStatus();
            if(businessStatus == 100) {
                throw new NuoNiuException("参数错误");
            }
            if(businessStatus == 1) {
                throw new NuoNiuException("任务已经关闭，不能修改");
            }
            Integer createUserId = oldCrmCallTask.getCreateUserId();
            if(!createUserId.equals(userInfo.getUserId())) {
                throw new NuoNiuException("不能修改被人的任务");
            }
        }
        if(StringUtils.isNotBlank(remarks) && StringUtils.length(remarks) > 200){
            throw new NuoNiuException("任务备注字数不能超过200");
        }
        this.saveOrUpdate(crmCallTask);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void closeTask(List<Long> ids) {
        UserInfo userInfo = UserThreadLocal.get();
        if(ids.size()  == 0) {
            throw new NuoNiuException("请选择外呼任务");
        }
        int closeTaskNum = baseMapper.closeTask(ids, userInfo.getCompanyId(), userInfo.getUserId());
        if(closeTaskNum > 0){
            /** 更新 客户外呼状态(指定任务) */
            customerService.updateCallTaskStateByCloseTask(userInfo,ids);
            /** 更新 联系人外呼状态(指定任务) */
            linkmanService.updateCallTaskStateByCloseTask(userInfo,ids);
        }
    }
    @Override
    public void batchDelete(List<Long> ids) {
        UserInfo userInfo = UserThreadLocal.get();
        if(ids.size()  == 0) {
            throw new NuoNiuException("请选择外呼任务");
        }
        Integer detailNum = callTaskDetailService.detailNum(ids);
        if(detailNum > 0) {
            throw new NuoNiuException("任务已经开始，不能删除");
        }
        baseMapper.batchDelete(ids,userInfo.getCompanyId(),userInfo.getUserId());
    }

    @Override
    public boolean checkMode(Long modeId) {
        UserInfo userInfo = UserThreadLocal.get();
        QueryWrapper<CrmCallTask> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("company_id",userInfo.getCompanyId());
        queryWrapper.eq("task_mode_id",modeId);
        return count(queryWrapper) > 0;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void updateTaskMobileCount(CrmCallTaskUpdateDto crmCallTaskUpdateDto) {
        Integer crmCallTaskId = crmCallTaskUpdateDto.getCrmCallTaskId();
        if(null == crmCallTaskId){
            log.info("更新任务号码数失败，任务ID 为空");
            return;
        }
        baseMapper.updateTaskMobileCount(crmCallTaskUpdateDto);
        /** 更新 任务进行状态*/
        if(null !=crmCallTaskId){
            CrmCallTask crmCallTask = this.getById(crmCallTaskId);
            this.updateTaskStatus(crmCallTask);
        }
    }

    @Override
    public void updateTaskStatus(CrmCallTask crmCallTask) {
        LocalDateTime now = LocalDateTime.now();
        Long id = crmCallTask.getId();
        Integer businessStatus = crmCallTask.getBusinessStatus();
        if(null == id || businessStatus == 1) {
            return;
        }
        Integer mobileCount = crmCallTask.getMobileCount();     //号码数量
        Integer dialedCount = crmCallTask.getDialedCount();     //已拨打数量
        LocalDate startTime = crmCallTask.getStartTime();   //任务开始时间
        LocalDate endTime = crmCallTask.getEndTime();       //任务结束时间
        /** 没有任务数*/
        if(mobileCount.equals(0)){
            return;
        }
        /** 开始时间 之前*/
        if(now.isBefore(startTime.atStartOfDay())){
            return;
        }
        /** 结束时间 之前*/
        if(now.isBefore(endTime.plusDays(1).atStartOfDay())){
            if(dialedCount.equals(0) ){
                //0.未开始
                baseMapper.updateTaskStatusById(id,0);
                return;
            }
            if(dialedCount < mobileCount){
                //1.进行中
                baseMapper.updateTaskStatusById(id,1);
                return;
            }
            if(mobileCount.equals(dialedCount)){
                //2.已完成
                baseMapper.updateTaskStatusById(id,2);
                return;
            }
        }
        /** 结束时间 之后*/
        if(dialedCount < mobileCount){
            //3.未完成
            baseMapper.updateTaskStatusById(id,3);
            return;
        }

    }



    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void checkAndUpdateTaskState() {
        /** 系统校验 全盘 表记录 超时未完成的任务*/
        baseMapper.checkUnfinishedTask();
        log.debug("校验外呼任务是否过期");
        List<Long> taskIdList = baseMapper.listTaskIds();
        if(taskIdList.size() > 0){
            String taskIds = StringUtils.join(taskIdList, ",");
            baseMapper.updateTaskState(taskIds);
            baseMapper.updateCrmCustorTaskState(taskIds);
            baseMapper.updateLinkManTaskState(taskIds);
        }
        log.debug("校验外呼任务是否过期:关闭数量：{}",taskIdList.size());
    }


}
